﻿using System;
using System.Collections.Generic;
using System.Data.Linq;
using System.Linq;
using System.Linq.Expressions;
using EOSCRM.Domain;
using EOSCRM.Linq.Audit;
using EOSCRM.Linq.Audit.Helpers;
using EOSCRM.Util;
using System.Data.Linq.Mapping;

namespace EOSCRM.Dao
{
    public class EventDao : EventProcessor
    {
        /*
        public Event Get(int id)
        {
            return _db.Events.SingleOrDefault(e => e.Id.Equals(id));
        }

        public EventDetail GetDetail(int id)
        {
            return _db.EventDetails.SingleOrDefault(e => e.Id.Equals(id));
        }

        public List<EventDetail> GetDetailList(int eventId)
        {
            return _db.EventDetails.Where(e => e.EventId.Equals(eventId)).ToList();
        }

        public Message Insert(Event obj)
        {
            try
            {
                _db.Events.InsertOnSubmit(obj);
                _db.SubmitChanges();

                return new Message(MessageConstants.I_CREATE_SUCCEED, MessageType.Info, "ghi log");
            }
            catch (Exception ex)
            {
                return ExceptionHandler.HandleInsertException(ex, "ghi log");
            }
        }

        public Message InsertDetail(EventDetail obj)
        {
            try
            {
                _db.EventDetails.InsertOnSubmit(obj);
                _db.SubmitChanges();

                return new Message(MessageConstants.I_CREATE_SUCCEED, MessageType.Info, "ghi log");
            }
            catch (Exception ex)
            {
                return ExceptionHandler.HandleInsertException(ex, "ghi log");
            }
        }*/
    }

    public enum AuditAction : byte
    {
        Insert,
        Update,
        Delete
    }

    public class EntityAuditRecord
    {
        public AuditAction Action { get; set; }

        public object Entity { get; set; }
        public LambdaExpression KeySelector { get; set; }

        public string EntityTable { get; set; }
        public string EntityTableKey { get; set; }

        private readonly List<ModifiedEntityProperty> _properties = new List<ModifiedEntityProperty>();
        public IList<ModifiedEntityProperty> ModifiedProperties { get { return _properties; } }
    }

    public class ModifiedEntityProperty
    {
        public string MemberName { get; set; }
        public string OldValue { get; set; }
        public string NewValue { get; set; }
    }

    public class EventProcessor : BaseDao
    {
        public void Process(IEnumerable<object> entities, AuditAction action)
        {
            ProcessRows(entities, action);
        }

        protected void ProcessRows(IEnumerable<object> entities, AuditAction action)
        {
            if (entities == null)
                return;

            foreach (object entity in entities)
            {
                var mmi = GetModifiedMembers(entity);

                foreach (MemberAudit ma in mmi)
                {
                    var mi = ma.Member;
                    if (mi.HasAttribute(typeof(ColumnAttribute)))
                    {
                        var value = new ModifiedEntityProperty
                                        {
                                            MemberName = mi.Name.SplitUpperCaseToString(),
                                            OldValue = ma.OriginalValue != null ? ma.OriginalValue.ToString() : "",
                                            NewValue = ma.CurrentValue != null ? ma.CurrentValue.ToString() : ""
                                        };

                        



                    }
                }
            }
        }

        public IEnumerable<MemberAudit> GetModifiedMembers(object entity)
        {
            ITable table = _db.GetTable(entity.GetType());
            return
                table.GetModifiedMembers(entity).Select(
                    mmi =>
                    new MemberAudit { Member = mmi.Member, CurrentValue = mmi.CurrentValue, OriginalValue = mmi.OriginalValue });
        }
    }
}

